// dotnet $DOTNET_CSC_DLL -nologo -t:library -r:"../../Backend/System.dll" -r:"../../Backend/System.Collections.dll" -r:"../../The Scroll of Taiwu_Data/Managed/0Harmony.dll" -r:"../../Backend/mscorlib.dll" -r:"../../Backend/System.Reflection.Primitives.dll" -r:"../../Backend/netstandard.dll" -r:"../../Backend/System.Reflection.Emit.ILGeneration.dll" -r:"../../Backend/GameData.dll" -r:"../../Backend/Redzen.dll" -r:"../../The Scroll of Taiwu_Data/Managed/TaiwuModdingLib.dll" -r:"../../Backend/System.Private.CoreLib.dll" -r:"../../Backend/System.Runtime.dll" -unsafe -optimize -deterministic -debug Backend.cs *.CS -out:Backend.dll
// -r:"../../The Scroll of Taiwu_Data/Managed/Mono.Cecil.dll" -r:"../../The Scroll of Taiwu_Data/Managed/System.Core.dll"   -r:"../../The Scroll of Taiwu_Data/Managed/System.Composition.AttributedModel.dll" -r:"../../Backend/System.Runtime.dll"
/**
 *  Neutron's Taiwu Collections
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

 // Backend: ProcessMethodCall -> CallMethod -> ...
 #define BACKEND

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using HarmonyLib;
using Utils;
using static Utils.Logger;
namespace ASmallCollectionsFromNeutron;
[TaiwuModdingLib.Core.Plugin.PluginConfig("ASmallCollectionsFromNeutron","Neutron3529","0.5.0")]
public class ASmallCollectionsFromNeutron : TaiwuModdingLib.Core.Plugin.TaiwuRemakePlugin {
    public override void Initialize()=>this.HarmonyInstance = new RobustHarmonyInstance(this.GetGuid());
    public override void Dispose()=>this.HarmonyInstance.UnpatchSelf();
    public RobustHarmonyInstance HarmonyInstance;
    public static int fpv=100;
    public static int mulF=32000;
    public static int maxV=32000;
    public static int divN=125;
    public static int minLife=1000;
    public static int minCombat=95;
    public static int minMain=200;
    public static int mapSight=200;
    public static int gbasc=100;
    public static int AFBegin=1;
    public static int N01APC=30;
    public static int N01ANC=0;
    public static int N01bloom=-1;
    public static int HuanYueNine=12000;
    public static int knowOther=1000;
    public static int WuLinTraitLevel=3;
    public static bool enterWorldGrandVision=false;
    public static short StoryHuanyue=Config.Character.DefKey.StoryHuanyue;
    public static short DefKey_VirginityFalse=Config.CharacterFeature.DefKey.VirginityFalse;
    public static short DefKey_Pregnant=Config.CharacterFeature.DefKey.Pregnant;
    public static object[] MakeLove_param;
    public static short DefKey_HaveElixir2=Config.CharacterFeature.DefKey.HaveElixir2;
    public static short DefKey_GreenMotherSpiderPoison2=Config.CharacterFeature.DefKey.GreenMotherSpiderPoison2;
    public static short DefKey_StarsRegulateBreath2=Config.CharacterFeature.DefKey.StarsRegulateBreath2;
    public static short DefKey_SupportFromShixiang2=Config.CharacterFeature.DefKey.SupportFromShixiang2;
    public static short DefKey_FulongServant=Config.CharacterFeature.DefKey.FulongServant;
    public static int pRegen=100;
    public static int pRegen2=100;
    public static int pLife=100;
    public static int pLife2=100;
    public static int pCombat=100;
    public static int pCombat2=100;
    public static int cRegen=1;
    public static int cLife=1;
    public static int cCombat=1;
    public static bool LSF_Show=true;
    public static bool LSF_Lucky=true;
    public static bool finishAllYellow=true;
    public static bool n05_4_0=false;
    public static bool n05_4_1=false;
    public static bool n05_4_2=false;
    public static bool n05_4_3=false;
    public static bool n05_4_4=false;
    public static bool n05_4_5=false;
    public static bool n05_4_6=false;
    public static bool n05_4_7=false;
    public static ushort RelationType_SwornBrotherOrSister=GameData.Domains.Character.Relation.RelationType.SwornBrotherOrSister;
    public static ushort RelationType_Mentor=GameData.Domains.Character.Relation.RelationType.Mentor;
    public static ushort RelationType_Mentee=GameData.Domains.Character.Relation.RelationType.Mentee;
    public static ushort RelationType_Friend=GameData.Domains.Character.Relation.RelationType.Friend;
    public static bool twoverwrite=false;
    public static int inhertmain=10000;
    public static int inhertcombat=10000;
    public static int inhertlife=10000;
    public static int pValue=10000;
    public static int pLevel=3;
    public static bool pmodifyzero=false;
    public static bool fulongCF=true;
    public static int totalTeachCount=100;
    public static int YiSu_ID=14;
    public static int GongSu_ID=19;
    public static int NeiGong_ID=20;
    public static int MiJue_ID=39;
    public static short MengJingZhongRen=203;
    public static bool enable_outline=true;
    public static List<Config.BreakGrid> AdditionalGrids0=new List<Config.BreakGrid>();
    public static List<Config.BreakGrid> AdditionalGrids1=new List<Config.BreakGrid>();
    public static List<Config.BreakGrid> AdditionalGrids2=new List<Config.BreakGrid>();
    public static List<Config.BreakGrid> AdditionalGrids3=new List<Config.BreakGrid>();
    public static List<Config.BreakGrid> AdditionalGrids4=new List<Config.BreakGrid>();
    // public static List<Config.BreakGrid> AdditionalGridsOnce0=new List<Config.BreakGrid>();
    // public static List<Config.BreakGrid> AdditionalGridsOnce1=new List<Config.BreakGrid>();
    // public static List<Config.BreakGrid> AdditionalGridsOnce2=new List<Config.BreakGrid>();
    // public static List<Config.BreakGrid> AdditionalGridsOnce3=new List<Config.BreakGrid>();
    // public static List<Config.BreakGrid> AdditionalGridsOnce4=new List<Config.BreakGrid>();
    public static Config.BreakGrid yellowFill=new Config.BreakGrid(-1,0);
    public static Config.BreakGrid yellowFill2=new Config.BreakGrid(-1,0);
    public static OpCode Op_instruction=OpCodes.Ldc_I4_1;
    public static bool N03_2=false;
    public static int TaiwuBloodFertility=-1;
    public static int GetProbAdjustOfCreatingCharacter=-1;
    public static int b1val=0;
    public static int b2val=0;
    public static int b3val=0;
    public static int b4val=0;
    public static string B06="GetLegendaryBookAddAvoidValues,GetLegendaryBookAddCombatSkillQualifications,GetLegendaryBookAddHitValues,GetLegendaryBookAddPenetrationResists,GetLegendaryBookAddPenetrations,GetLegendaryBookAddPropertyValue,SetLegendaryBookSkillSlot,SetLegendaryBookWeaponSlot";
    public static int b7val=0;

    public static uint offset_lifeSkillQualificationGrowthType=unchecked((uint)(-1));
    public static uint offset_combatSkillQualificationGrowthType=unchecked((uint)(-1));
    public unsafe static void GetOffset(){
        var character=new GameData.Domains.Character.Character();
        var size=character.GetSerializedSize();
        var bs=new byte[size+100];
        FieldInfo _lifeSkillQualificationGrowthType=typeof(GameData.Domains.Character.Character).GetField("_lifeSkillQualificationGrowthType",(BindingFlags)(-1));
        FieldInfo _combatSkillQualificationGrowthType=typeof(GameData.Domains.Character.Character).GetField("_combatSkillQualificationGrowthType",(BindingFlags)(-1));
        _lifeSkillQualificationGrowthType.SetValue(character,(sbyte)35);
        _combatSkillQualificationGrowthType.SetValue(character,(sbyte)29);
        fixed(byte*pData=bs){
            character.Serialize(pData);
            int counter_35=0;
            int counter_29=0;
            for(uint i=0;i<bs.Length;i++){
                // logger("bit "+i+", content="+bs[i]);
                switch(bs[i]){
                    case 35:offset_lifeSkillQualificationGrowthType  =i;counter_35++;if(counter_29>=2){logwarn("序列化结果中存在至少两个35, 由此N01bloom无效");N01bloom=-1;}continue;
                    case 29:offset_combatSkillQualificationGrowthType=i;counter_29++;if(counter_29>=2){logwarn("序列化结果中存在至少两个35, 由此N01bloom无效");N01bloom=-1;}continue;
                    default:continue;
                    // default:throw new Exception("序列化结果中有不为0,35,29的项");
                }
            }
            if(counter_35!=1){
                N01bloom=-1;
                logwarn("序列化结果不存在35, 由此N01bloom无效");
            }
            if(counter_29!=1){
                N01bloom=-1;
                logwarn("序列化结果不存在29, 由此N01bloom无效");
            }
        }
        logger("offsets: lifeSkillQualificationGrowthType="+offset_lifeSkillQualificationGrowthType+", combatSkillQualificationGrowthType="+offset_combatSkillQualificationGrowthType);
    }
    public void ReadAdditionals(string key, List<Config.BreakGrid> AdditionalGrids){
        AdditionalGrids.Clear();
        string Additionals="";
        if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref Additionals)){
            if(Additionals.Length>0) try {
                foreach (string gc in Additionals.Split(",")){
                    var tst=gc.Split("x");
                    sbyte count=(sbyte)int.Parse(tst[1].Trim());
                    short bonusType=-1;
                    var id=tst[0].Trim();
                    if(Parser.Name2Id(tst[0],Config.CharacterFeature.Instance, ref bonusType))AdditionalGrids.Add(new Config.BreakGrid(bonusType,count));
                }
            } catch (Exception e){
                throw new Exception("额外黄点格子（"+key+"）值有误，请修改字符串格式，或者将字符串置空，错误信息为：\n"+e.Message);
            }
        }
    }

    public static List<short> manual_feature_id=new List<short>();
    public void MFid(string key){
        manual_feature_id.Clear();
        string Additionals="";
        GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref Additionals);
        if(Additionals.Length>0) try {
            short cfid=0;
            foreach (string txt in Additionals.Split(",")){
                if(Parser.Name2Id(txt,Config.CharacterFeature.Instance, ref cfid))manual_feature_id.Add(cfid);
            }
        } catch (Exception e){
            throw new Exception("人物特性字符串（"+key+"）值有误，请修改字符串格式，或者将字符串置空，错误信息为：\n"+e.Message);
        }
    }

    //public static List<sbyte> building_maxLv=new List<sbyte>();
    public void buildingMaxLv(string key){
        //building_maxLv.Clear();
        string Additionals="";
        if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref Additionals) && Additionals.Length>0) try {
            foreach (string gc in Additionals.Split(",")){
                var tst=gc.Split("=");
                sbyte count=(sbyte)int.Parse(tst[1].Trim());
                short bonusType=-1;
                var id=tst[0].Trim();
                if(Parser.Name2Id(tst[0],Config.BuildingBlock.Instance, ref bonusType))typeof(Config.BuildingBlockItem).GetField("MaxLevel",(BindingFlags)(-1)).SetValue(Config.BuildingBlock.Instance[bonusType],(sbyte)count);
            }
        } catch (Exception e){
            throw new Exception("建筑名称字符串（"+key+"）值有误，请修改字符串格式，或者将字符串置空\n请注意，这个错误的发生会导致部分建筑数据被修改，如果希望使用原版数据，需重启游戏。\n错误信息为：\n"+e.Message);
        }
    }
    private bool enable(string key){
        try {
            return _enable(key);
        } catch(Exception ex){
            logwarn("enable 出错，出错键值为\""+key+"\"，错误原因是"+ex.Message);
            return false;
        }
    }
    private bool _enable(string key){
        bool enabled=false;
        if(key=="N01") {
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref AFBegin) && AFBegin>-1){
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01WuLin", ref WuLinTraitLevel);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01APC", ref N01APC);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01ANC", ref N01ANC);

                if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01bloom", ref N01bloom) && N01bloom!=-1){
                    GetOffset();
                };
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01minLife", ref minLife);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01minCombat", ref minCombat);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01minMain", ref minMain);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "HuanYueNine", ref HuanYueNine);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N01FuLongFriend", ref fulongCF);
                if(HuanYueNine>0){
                    StoryHuanyue=(short)typeof(Config.Character.DefKey).GetField("StoryHuanyue").GetValue(null);
                    this.HarmonyInstance.PatchAll(typeof(HuanYue));
                }

                DefKey_HaveElixir2=(short)typeof(Config.CharacterFeature.DefKey).GetField("HaveElixir2").GetValue(null);
                DefKey_GreenMotherSpiderPoison2=(short)typeof(Config.CharacterFeature.DefKey).GetField("GreenMotherSpiderPoison2").GetValue(null);
                DefKey_StarsRegulateBreath2=(short)typeof(Config.CharacterFeature.DefKey).GetField("StarsRegulateBreath2").GetValue(null);
                DefKey_SupportFromShixiang2=(short)typeof(Config.CharacterFeature.DefKey).GetField("SupportFromShixiang2").GetValue(null);
                DefKey_FulongServant=(short)typeof(Config.CharacterFeature.DefKey).GetField("FulongServant").GetValue(null);
                return true;
            } else {
                return false;
            }
        } else if(key=="N02-post") {
            this.ReadAdditionals("N02-0", AdditionalGrids0);
            this.ReadAdditionals("N02-1", AdditionalGrids1);
            this.ReadAdditionals("N02-2", AdditionalGrids2);
            this.ReadAdditionals("N02-3", AdditionalGrids3);
            this.ReadAdditionals("N02-4", AdditionalGrids4);
            // this.ReadAdditionals("N02-00", AdditionalGridsOnce0);
            // this.ReadAdditionals("N02-01", AdditionalGridsOnce1);
            // this.ReadAdditionals("N02-02", AdditionalGridsOnce2);
            // this.ReadAdditionals("N02-03", AdditionalGridsOnce3);
            // this.ReadAdditionals("N02-04", AdditionalGridsOnce4);
            string Fill="";
            short bonusType=-1;
            if(!GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N02-enable_outline", ref enable_outline)){
                enable_outline=true;
            }
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N02-Fill2", ref Fill)){
                var sp=Fill.Split("x");
                var count=100;
                if(sp.Length>1){
                    count=sbyte.Parse(sp[1].Trim())
                }
                if(Parser.Name2Id(sp[0],Config.SkillBreakPlateGridBonusType.Instance, ref bonusType)){
                    yellowFill2=new Config.BreakGrid(bonusType,count);
                }
            }
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N02-Fill", ref Fill)){
                var sp=Fill.Split("x");
                var count=100;
                if(sp.Length>1){
                    count=sbyte.Parse(sp[1].Trim())
                }
                if(Parser.Name2Id(sp[0],Config.SkillBreakPlateGridBonusType.Instance, ref bonusType)){
                    yellowFill=new Config.BreakGrid(bonusType,count);
                    Op_instruction=OpCodes.Ldc_I4_0;
                }
            }
            return AdditionalGrids0.Count+AdditionalGrids1.Count+AdditionalGrids2.Count+AdditionalGrids3.Count+AdditionalGrids4.Count>0 || bonusType>=0;
        }else if(key=="N03") {
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref enabled) && enabled)GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N03-2", ref N03_2);
            return enabled;
        } if(key=="N04") {
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref enabled) && enabled){
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "NmulF", ref mulF);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "NmaxV", ref maxV);
                GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "NdivN", ref divN);
                // GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N04pLevel", ref pLevel);
                // GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N04pValue", ref pValue);
                // GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N04pmz", ref pmodifyzero);
                //GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N04poison", ref poison);
                //GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N04plevel", ref plevel);
                return mulF>divN && maxV>0;
            }
        } else if(key=="N05") {
            return (GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref LSF_Show)|GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-2", ref LSF_Lucky)|GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-3", ref finishAllYellow)) && (LSF_Show||LSF_Lucky||finishAllYellow);
        } else if(key=="N05-4") {
            bool y=false;
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-0", ref n05_4_0);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-1", ref n05_4_1);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-2", ref n05_4_2);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-3", ref n05_4_3);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-4", ref n05_4_4);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-5", ref n05_4_5);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-6", ref n05_4_6);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4-7", ref n05_4_7);
            return finishAllYellow && GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N05-4", ref y) && y;
        } else if(key=="N06") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref gbasc) && gbasc>0;
        } else if(key=="N09S") {
            int ciTangAdd=120;
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref ciTangAdd) && ciTangAdd!=0;
        } else if(key=="N10") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref fpv) && fpv>0;
        } else if(key=="N13") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref knowOther) && knowOther>0;
        } else if(key=="N14") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref mapSight) && mapSight>0;
        } else if(key=="N27") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref totalTeachCount) && totalTeachCount>0;
        } else if(key=="N27-2"){
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pRegen", ref pRegen);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pRegen2", ref pRegen2);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pLife", ref pLife);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pLife2", ref pLife2);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pCombat", ref pCombat);
            GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "pCombat2", ref pCombat2);
            if((GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "cRegen", ref cRegen)
                |GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "cLife", ref cLife)
                |GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "cCombat", ref cCombat)
            ) && (cLife+cRegen+cCombat>0)){
                RelationType_Mentor=(ushort)typeof(GameData.Domains.Character.Relation.RelationType).GetField("Mentor",(BindingFlags)(-1)).GetValue(null);
                RelationType_Mentee=(ushort)typeof(GameData.Domains.Character.Relation.RelationType).GetField("Mentee",(BindingFlags)(-1)).GetValue(null);
                RelationType_SwornBrotherOrSister=(ushort)typeof(GameData.Domains.Character.Relation.RelationType).GetField("SwornBrotherOrSister",(BindingFlags)(-1)).GetValue(null);
                RelationType_Friend=(ushort)typeof(GameData.Domains.Character.Relation.RelationType).GetField("Friend",(BindingFlags)(-1)).GetValue(null);
                return true;
            } else {
                return false;
            }
        } else if(key=="N28") {
            int switcher=0;
            if(GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref switcher)){
                twoverwrite=switcher==2;
                return switcher>0;
            } else {
                return false;
            }
        } else if(key=="N29") {
            return (GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N29inhertmain", ref inhertmain)|GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N29inhertcombat", ref inhertcombat)|GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "N29inhertlife", ref inhertlife))&& (inhertmain+inhertcombat+inhertlife>0);
        } else if(key=="N37") {
            buildingMaxLv(key);
        } else if(key=="N38") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref GetProbAdjustOfCreatingCharacter) && GetProbAdjustOfCreatingCharacter>=0;
        } else if(key=="N39") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref TaiwuBloodFertility) && TaiwuBloodFertility>=0;
        } else if(key=="B1") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref b1val) && b1val>0;
        } else if(key=="B2") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref b2val) && b2val>0;
        } else if(key=="B3") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref b3val) && b3val>1;
        } else if(key=="B4") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref b4val) && b4val>1;
        } else if(key=="B6") {
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref B06) && B06.Length>1;
        } else if(key=="B7") {
            // GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, "B7_2", ref b07_2);
            return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref b7val) && b7val>0;
        }
        return GameData.Domains.DomainManager.Mod.GetSetting(this.ModIdStr, key, ref enabled) && enabled;
    }
    public override void OnEnterNewWorld() { // 试图修复开局地图红字
        enterWorldGrandVision=false;
    }
    public override void OnModSettingUpdate(){
        this.HarmonyInstance.UnpatchSelf();
        if(enable("NForceOFF")){return;}
        // if(enable("NPatchPregnant")){
        //     DefKey_VirginityFalse=(short)typeof(Config.CharacterFeature.DefKey).GetField("VirginityFalse",(BindingFlags)(-1)).GetValue(null);
        //     DefKey_Pregnant=(short)typeof(Config.CharacterFeature.DefKey).GetField("Pregnant",(BindingFlags)(-1)).GetValue(null);
        //     MakeLove_param=new object[]{DefKey_VirginityFalse,true};
        //     this.HarmonyInstance.PatchAll(typeof(PatchPregnant));
        // }
        if(enable("N01")){
            this.HarmonyInstance.PatchAll(typeof(AllFeature));
            MFid("N01-2");
        }
        if(enable("N02"))this.HarmonyInstance.PatchAll(typeof(AllYellowPerkPrefix));
        if(enable("N02-post"))this.HarmonyInstance.PatchAll(typeof(AllYellowPerkPostfix));
        if(enable("N02-Ex"))this.HarmonyInstance.PatchAll(typeof(ExtendBreak));
        if(enable("N02-YaEx"))this.HarmonyInstance.PatchAll(typeof(YaExtendBreak));
        if(enable("N03"))this.HarmonyInstance.PatchAll(typeof(AlwaysCapture));
        if(enable("N04"))this.HarmonyInstance.PatchAll(typeof(WeaponModifier));
        if(enable("YaN04-Nolife")){
            this.HarmonyInstance.PatchAll(typeof(PoisonPlusNoLife));
        } else if(enable("YaN04-poison"))this.HarmonyInstance.PatchAll(typeof(PoisonModifier));
        if(enable("N13"))this.HarmonyInstance.PatchAll(typeof(TaiwuDomainUpdateCombatSkillBookReadingProgress)); // N05-4 的patch顺序需要在 N13之后，因此将N13提前
        if(enable("N05")){
            this.HarmonyInstance.PatchAll(typeof(LuckyShow));
        }
        if(enable("N05x")){
            this.HarmonyInstance.PatchAll(typeof(YaN05x));
            //this.HarmonyInstance.PatchAll(typeof(N05x)); //works with  Op_instruction=OpCodes.Ldc_I4_1;
            if(enable("N05-4"))this.HarmonyInstance.PatchAll(typeof(TaiwuDomainUpdateCombatSkillBookReadingProgress_break));
        }
        if(enable("N06"))this.HarmonyInstance.PatchAll(typeof(BreakPlus));
        if(enable("N07"))this.HarmonyInstance.PatchAll(typeof(TransNext));
        if(enable("N09S"))this.HarmonyInstance.PatchAll(typeof(CiTang_Backend_NoAuthCost));
        if(enable("N10"))this.HarmonyInstance.PatchAll(typeof(FastPractice));
        if(enable("N11"))this.HarmonyInstance.PatchAll(typeof(MakeSpeedup));
        if(enable("N12"))this.HarmonyInstance.PatchAll(typeof(Speedup));
        if(enable("N14"))this.HarmonyInstance.PatchAll(typeof(RevealMap));
        if(enable("N16"))this.HarmonyInstance.PatchAll(typeof(ZhouBaPi));
        if(enable("N24"))this.HarmonyInstance.PatchAll(typeof(BuildResource));
        if(enable("N25"))this.HarmonyInstance.PatchAll(typeof(Qinggong_Move));
        if(enable("N27"))this.HarmonyInstance.PatchAll(typeof(MustLearn));
        if(enable("N27-2")){
            this.HarmonyInstance.PatchAll(typeof(LuckyTaiwu));
        }
        if(enable("N28")){this.HarmonyInstance.PatchAll(typeof(TaiwuLegency));}
        if(enable("N29")){this.HarmonyInstance.PatchAll(typeof(TaiwuLegencyAttribute));}
        if(enable("N30")){this.HarmonyInstance.PatchAll(typeof(AutoUpgrade));}
        if(enable("N31-0")){this.HarmonyInstance.PatchAll(typeof(YaLuckyReading));}
        else if(enable("N31")){this.HarmonyInstance.PatchAll(typeof(LuckyReading));}
        if(enable("N36")){this.HarmonyInstance.PatchAll(typeof(LuckyReadingReadsAll));}
        if(enable("N33")){this.HarmonyInstance.PatchAll(typeof(Printing));}
        enable("N37");
        if(enable("N38")){this.HarmonyInstance.PatchAll(typeof(DecreasePopulation));}
        if(enable("N39")){this.HarmonyInstance.PatchAll(typeof(TaiwuBlood));}
        if(enable("N40")){this.HarmonyInstance.PatchAll(typeof(KillBadChecker));}
        if(enable("BF0-A")){this.HarmonyInstance.PatchAll(typeof(Master));}
        if(enable("BF0-B")){this.HarmonyInstance.PatchAll(typeof(Master0));}
        if(enable("BF1")){this.HarmonyInstance.PatchAll(typeof(MoveGrid));}
        if(enable("B1")){this.HarmonyInstance.PatchAll(typeof(MasterExp));}
        if(enable("B2")){this.HarmonyInstance.PatchAll(typeof(MasterDoctor));}
        if(enable("B3")){this.HarmonyInstance.PatchAll(typeof(MasterMartialArtistSkill));}
        if(enable("B4")){this.HarmonyInstance.PatchAll(typeof(MasterLiteratiSkill));}
        if(enable("B5")){this.HarmonyInstance.PatchAll(typeof(BookSummon));}
        if(enable("B6")){this.HarmonyInstance.PatchAll(typeof(BookOwnersIsTaiwu));}
        if(enable("B7")){
            if(b7val==1){this.HarmonyInstance.PatchAll(typeof(TaiwuIsComboMaster));}
            else if(b7val==2){this.HarmonyInstance.PatchAll(typeof(OnlyTaiwuIsComboMaster));}
            else if(b7val==3){this.HarmonyInstance.PatchAll(typeof(PeopleAreComboMaster));}
        }
        if(enable("B8")){this.HarmonyInstance.PatchAll(typeof(UndeadCricket));}
        if(enable("B9")){this.HarmonyInstance.PatchAll(typeof(Science));}
        if(enable("B10")){this.HarmonyInstance.PatchAll(typeof(BetterAssign));}
        if(enable("B11")){this.HarmonyInstance.PatchAll(typeof(FastTao));}
        if(enable("B12")){this.HarmonyInstance.PatchAll(typeof(SetLegendaryBookBonusCountYinYang));}
        if(enable("B13")){this.HarmonyInstance.PatchAll(typeof(MaximizeCultureAndSafety));}
        if(enable("B14")){this.HarmonyInstance.PatchAll(typeof(EventHelperStartSelectSoul));}
        if(enable("B15")){this.HarmonyInstance.PatchAll(typeof(BuildingDomainGetTaiwuShrineStudentList));}
    }
    public class PoisonModifier {
        [HarmonyPatch(typeof(GameData.Domains.Item.ItemDomain),"SetAttachedPoisons")]
        public static void Prefix(ref short templateId){
            if(((ushort)templateId)<54)templateId+=(short)(8-(templateId%9)); // 淬毒
            else if(templateId>129 && templateId<202)templateId+=(short)(11-((templateId+2)%12)); // 解毒
        }
    }
    public class PoisonPlusNoLife {
        [HarmonyPatch(typeof(GameData.Domains.Item.ItemDomain),"SetAttachedPoisons")]
        public static void Prefix(ref short templateId){
            if(templateId<54)templateId+=(short)(8-(templateId%9)); // 淬毒
            else if(templateId>129 && templateId<202)templateId+=(short)(11-((templateId+2)%12)); // 解毒
        }
    }
    public class BuildResource {
        public static short Max1(short a){
            return Math.Max(a,(short)1);
        }
        [HarmonyTranspiler]
        [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"OfflineUpdateOperation")]
        public static IEnumerable<CodeInstruction> Transpiler_Max(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.BuildingBlockItem).GetField("OperationType")),
                    new CodeMatch(OpCodes.Ldelem_I2)
                ).Repeat( matcher => // Do the following for each match
                    matcher.Advance(2).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Call,typeof(BuildResource).GetMethod("Max1"))
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        [HarmonyTranspiler]
        [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"CanBuild")]
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldloc_S),
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.BuildingBlockItem).GetField("Type"))
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .SetAndAdvance(
                        OpCodes.Nop,null
                    )
                    .SetAndAdvance(
                        OpCodes.Ldc_I4_S,(int)EBuildingBlockType.Building
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        [HarmonyTranspiler]
        [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"CanUpgrade")] // 逻辑与CanBuild一致，但这里的ldloc是ldloc_1
        public static IEnumerable<CodeInstruction> Transpiler_Upgrade(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.BuildingBlockItem).GetField("Type"))
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .SetAndAdvance(
                        OpCodes.Pop,null
                    )
                    .InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_S,(int)EBuildingBlockType.Building)
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        [HarmonyTranspiler]
        [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"CanAutoUpgrade")] // 逻辑与CanUpgrade一致
        public static IEnumerable<CodeInstruction> Transpiler_AutoUpgrade(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.BuildingBlockItem).GetField("Type"))
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .SetAndAdvance(
                        OpCodes.Pop,null
                    )
                    .InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_S,(int)EBuildingBlockType.Building)
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"ParallelUpdate")]
    public class AutoUpgrade {
        public static Type[] args=new Type[]{
            typeof(GameData.Domains.Building.ParallelBuildingModification),
            typeof(short),
            typeof(Config.BuildingBlockItem),
            typeof(GameData.Domains.Building.BuildingBlockKey),
            typeof(GameData.Domains.Building.BuildingBlockData)
        };
        public static MethodInfo OfflineUpdateOperation=typeof(GameData.Domains.Building.BuildingDomain).GetMethod("OfflineUpdateOperation",(BindingFlags)(-1),null,args,null);
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Call,OfflineUpdateOperation)
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldarg_1), // 多传一个context能死是么

                        new CodeInstruction(OpCodes.Ldarg_0),
                        new CodeInstruction(OpCodes.Ldfld,typeof(GameData.Domains.Building.BuildingDomain).GetField("_buildingOperatorDict", (BindingFlags)(-1)))
                        // _buildingOperatorDict
//                        new CodeInstruction(OpCodes.Ldarg_0), // GameData.Domains.Building.BuildingDomain
//                        new CodeInstruction(OpCodes.Ldarg_S,4), // GameData.Domains.Building.BuildingBlockKey
//                        new CodeInstruction(OpCodes.Ldarg_S,5), // GameData.Domains.Building.BuildingBlockData
//                        new CodeInstruction(OpCodes.Ldarg_0),
//                        new CodeInstruction(OpCodes.Ldfld,typeof(GameData.Domains.Building.BuildingDomain).GetField("_buildingOperatorDict",(BindingFlags)(-1))),
//                        new CodeInstruction(OpCodes.Call,typeof(AutoUpgrade).GetMethod("Process"))
                    ).SetAndAdvance(
                        OpCodes.Call,typeof(AutoUpgrade).GetMethod("Process")
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        public static void Process(
            GameData.Domains.Building.BuildingDomain that,
            GameData.Domains.Building.ParallelBuildingModification modification,
            short settlementId,
            Config.BuildingBlockItem configData,
            GameData.Domains.Building.BuildingBlockKey blockKey,
            GameData.Domains.Building.BuildingBlockData blockData,
            GameData.Common.DataContext context,
            Dictionary<GameData.Domains.Building.BuildingBlockKey, GameData.Domains.Character.CharacterList> _buildingOperatorDict
        ){
            bool should_keep=blockData.OperationType!=2/*AddBuildingDemolitionCompleted*/; // blockData.OperationType==0 /*AddBuildingConstructionCompleted*/|| blockData.OperationType==1/*AddBuildingUpgradingCompleted*/
            OfflineUpdateOperation.Invoke(that, new object[]{modification, settlementId, configData, blockKey, blockData});
            GameData.Domains.Character.CharacterList currworker;
            if(should_keep && _buildingOperatorDict.TryGetValue(blockKey,out currworker) && that.CanUpgrade(blockKey)){
                var tmp=currworker.GetCollection().ToArray();
                int counter=0;
                foreach(int cid in tmp){
                    counter+=Convert.ToInt32(cid>0);
                }
                if(counter>0){
                    that.Upgrade(context, blockKey, tmp);
                    modification.FreeOperator = false;
                }
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Map.MapDomain),"Move", new Type[]{typeof(GameData.Common.DataContext),typeof(short),typeof(bool)})]
    public class Qinggong_Move {
        public static void Prefix(GameData.Domains.Map.MapDomain __instance, ref bool notCostTime, bool ____teleportMove, GameData.Common.DataContext context, short destBlockId){
            //logger("开始移动");
            if(notCostTime || ____teleportMove){
                return;
            }
            //logger("开始处理内力逻辑");
            var taiwu=GameData.Domains.DomainManager.Taiwu.GetTaiwu();
            var loc=taiwu.GetLocation();
            loc.BlockId = destBlockId;
            int num = taiwu.GetCurrNeili() - (int)(__instance.GetBlock(loc).GetConfig().MoveCost) * GameData.Domains.DomainManager.Taiwu.GetMoveTimeCostPercent() / 100;
            if(num>=0){
                taiwu.SetCurrNeili(num,context);
                notCostTime=true;
            }
            //logger("结束处理流程，目前notCostTime="+notCostTime);
            // TODO : 可以在这里加入自动存取物品逻辑。
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"TeachSkill")]
    public class CiTang_Backend_NoAuthCost {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldc_I4_1),
                    new CodeMatch(OpCodes.Add),
                    new CodeMatch(OpCodes.Conv_U2),
                    new CodeMatch(OpCodes.Ldarg_1),
                    new CodeMatch(OpCodes.Call,typeof(GameData.Domains.Building.BuildingDomain).GetMethod("SetShrineBuyTimes"))
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .SetAndAdvance(
                        OpCodes.Ldc_I4_0,null
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Map.MapDomain),"GetNeighborBlocks")]
    public class RevealMap {
        public static void Prefix(ref int maxSteps){
            if(enterWorldGrandVision){
                maxSteps=Math.Max(maxSteps,mapSight);
            } else {
                enterWorldGrandVision=true;
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"GetMakeItems")]
    public class WeaponModifier {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(i=> i.opcode==OpCodes.Call && ((MethodInfo)i.operand).Name == "GetElement_MakeItemDict")
                ).Repeat( matcher => // Do the following for each match
                    matcher
                    .Advance(1)
                    .InsertAndAdvance(
                        new CodeInstruction(OpCodes.Call,typeof(WeaponModifier).GetMethod("MZhujianGA"))
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        public static unsafe GameData.Domains.Building.MakeItemData MZhujianGA(
            GameData.Domains.Building.MakeItemData makeItemData
        ){
            fixed(short*p=makeItemData.MaterialResources.Items){
                for(int i=0;i<6;i++){
                    *(p+i)=(short)Math.Min(((int)(*(p+i))*mulF)/divN,maxV);
                }
            }
            return makeItemData;
        }
        // public static void Postfix(List<GameData.Domains.Item.Display.ItemDisplayData> __result, GameData.Common.DataContext context) {
            // if(plevel>0){
                // GameData.Domains.Item.PoisonsAndLevels prevAttachedPoison = new GameData.Domains.Item.PoisonsAndLevels(new short[]{(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel});
                // for(int i=0;i<__result.Count;i++) {
                    // var key=__result[i].Key;
                    // if(key.ItemType<4 && GameData.Domains.Item.ItemTemplateHelper.IsPoisonable(key.ItemType, key.TemplateId)) {
                        // GameData.Domains.Item.ItemBase item=;
                        // byte state = item.GetModificationState();
                        // state = ModificationStateHelper.Activate(state, 1);
                        // item.SetModificationState(currState2, context);
                    // }
                // }
            // }
        // }
        public static MethodInfo SetElement_PoisonItems=typeof(GameData.Domains.Item.ItemDomain).GetMethod("SetElement_PoisonItems",(BindingFlags)(-1));
        public static FieldInfo _poisonItems=typeof(GameData.Domains.Item.ItemDomain).GetField("_poisonItems",(BindingFlags)(-1));
        public static FieldInfo _poisons=typeof(GameData.Domains.Item.PoisonEffects).GetField("_poisons",(BindingFlags)(-1));
        // [HarmonyPostfix]
        // [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"AddItemPoison")]
        public unsafe static void Pstfx(GameData.Common.DataContext context, ValueTuple<bool, GameData.Domains.Item.Display.ItemDisplayData> __result){
            var dict=(Dictionary<int, GameData.Domains.Item.PoisonEffects>)_poisonItems.GetValue(GameData.Domains.DomainManager.Item);
            var itemId=__result.Item2.Key.Id;
            GameData.Domains.Item.PoisonEffects effect;
            if(dict.TryGetValue(itemId,out effect)){ // 1 是淬毒的意思
                // PoisonsAndLevels.SetValue(effect, new GameData.Domains.Item.PoisonsAndLevels(new short[]{(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel,(short)poison,(short)plevel}) );
                var pal=effect.GetAllPoisonsAndLevels();
//                for (int i = 0; i < 6; i++) {
//                    logger("pre:"+*(pal.Values + i)+" "+*(pal.Levels+ i)+">="+pValue +""+pLevel);
//                }
//                logger("淬毒开始");

                for (int i = 0; i < 6; i++) {
                    if(pmodifyzero || *(pal.Levels+ i)>0) {
                        *(pal.Values + i) = Math.Max(*(pal.Values + i),(short)pValue);
                        *(pal.Levels+ i) = Math.Max(*(pal.Levels + i),(sbyte)pLevel);
                    }
//                    logger("process:"+*(pal.Values + i)+" "+*(pal.Levels+ i)+">="+pValue +""+pLevel);
                }


                TypedReference reference = __makeref(effect);
                _poisons.SetValueDirect(reference, pal);
//                pal=effect.GetAllPoisonsAndLevels();
//                for (int i = 0; i < 6; i++) {
//                    logger("post:"+*(pal.Values + i)+" "+*(pal.Levels+ i)+">="+pValue +""+pLevel);
//                }

                var args=new object[]{itemId, effect, context};
                SetElement_PoisonItems.Invoke(GameData.Domains.DomainManager.Item, args);
            }
        }
    }
    public class Speedup{
        [HarmonyPrefix]
        [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"GetBaseReadingSpeed")]
        public static bool Prefix(ref sbyte __result){
            __result=100;
            return false;
        }
        [HarmonyPostfix]
        [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"GetReadingSpeedBonus")]
        public static int Postfix(int res){
            return Math.Max(res*50,600);
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"StartMakeItem")]
    public class MakeSpeedup{
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.MakeItemSubTypeItem).GetField("Time"))
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Pop,null
                    ).InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_0))
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
    public class LuckyShow {
        public static void Postfix(GameData.Domains.Taiwu.SkillBreakPlate plate){
            for(int row=0;row<plate.Grids.Length;row++)for(int col=0;col<plate.Grids[row].Length-(1&~row);col++){
                if(LSF_Lucky)plate.Grids[row][col].SuccessRateFix=120;
                if(finishAllYellow && plate.Grids[row][col].BonusType >= 0){
                    plate.Grids[row][col].State=2;
                }else if(LSF_Show){
                    plate.Grids[row][col].State=Math.Max(plate.Grids[row][col].State,(sbyte)0);
                }
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
    public class N05x {
        public static void Postfix(GameData.Domains.Taiwu.SkillBreakPlate plate){
            var t=plate.Grids[0][0];
            plate.Grids[0][0]=plate.Grids[plate.ExtraPoint.Item1][plate.ExtraPoint.Item2];
            plate.Grids[plate.ExtraPoint.Item1][plate.ExtraPoint.Item2]=t;
            var tmp=plate.ExtraPoint;
            plate.ExtraPoint=(0,0);
            if(plate.StartPoint==(0,0))plate.StartPoint=tmp; else if(plate.EndPoint==(0,0))plate.EndPoint=tmp;
            t=plate.Grids[0][1];
            plate.Grids[0][1]=plate.Grids[plate.StartPoint.Item1][plate.StartPoint.Item2];
            plate.Grids[plate.StartPoint.Item1][plate.StartPoint.Item2]=t;
            if(plate.EndPoint==(0,1))plate.EndPoint=plate.StartPoint;
            plate.StartPoint=(0,1);
            t=plate.Grids[1][0];
            plate.Grids[1][0]=plate.Grids[plate.EndPoint.Item1][plate.EndPoint.Item2];
            plate.Grids[plate.EndPoint.Item1][plate.EndPoint.Item2]=t;
            plate.EndPoint=(1,0);
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.BreakPlateRegions),"GetRandomPointInRegion")]
    public class YaN05x {
        static int _YaN05x_status=0;
        public static bool Prefix(ref ValueTuple<int, int> __result){
            switch(_YaN05x_status){
                case 0:__result=(0,0);_YaN05x_status++;break;
                case 1:__result=(1,0);_YaN05x_status++;break; // 保证起点终点相邻
                case 2:__result=(0,1);_YaN05x_status=0;break;
                default:throw new Exception("YaN05x 被错误修改");
            }
            return false;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
    public class TransNext{
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldloc_S), // match method 2
                    new CodeMatch(OpCodes.Callvirt,typeof(Redzen.Random.IRandomSource).GetMethod("Next",new Type[]{typeof(int)})),
                    new CodeMatch(OpCodes.Ldloc_S), // match method 2
                    new CodeMatch(i=>i.opcode==OpCodes.Callvirt&&((MethodInfo)i.operand).Name=="get_Count")
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Ldc_I4_1,null
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CalcEvaluationList")]
    public class LuckyReading {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Callvirt,typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("GetReadInCombatCount",new Type[0]))
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Pop,null
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_8)
                    )
                ).InstructionEnumeration();
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Call,typeof(GameData.Utilities.RedzenHelper).GetMethod("CheckPercentProb"))
                ).Repeat( matcher => // Do the following for each match
                    matcher.InsertAndAdvance(
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Ldc_I4_S,100)
                    ).Advance(1)
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain), "UpdateReadingProgressInCombat")]
    public class LuckyReadingReadsAll {
        public static bool block=true;
        public static sbyte SkillBooks=(sbyte)((ushort)typeof(GameData.Domains.Item.ItemDomainHelper.DataIds).GetField("SkillBooks").GetValue(null));//(sbyte)GameData.Domains.Item.ItemDomainHelper.DataIds.SkillBooks=10;
        public static void Prefix(GameData.Domains.Taiwu.TaiwuDomain __instance, GameData.Common.DataContext context, ref GameData.Domains.Item.ItemKey ____curReadingBook, ref Dictionary<GameData.Domains.Item.ItemKey, GameData.Domains.Taiwu.ReadingBookStrategies> ____readingBooks, GameData.Domains.Item.ItemKey[] ____referenceBooks){
            if(block){
                block=false;

                // pre

                var taiwu = __instance.GetTaiwu();
                var curr=__instance.GetCurReadingBook();
                var inventory = taiwu.GetInventory().Items;
                var lst=new List<GameData.Domains.Item.ItemKey>();

                GameData.Domains.Item.ItemKey[] keys=new GameData.Domains.Item.ItemKey[____referenceBooks.Length];
                for (int i = 0; i < ____referenceBooks.Length; i++){
                    keys[i]=____referenceBooks[i];
                    ____referenceBooks[i]=GameData.Domains.Item.ItemKey.Invalid;
                }

                // process

                foreach (var key in inventory.Keys) { // 防止迭代器失效
                    if(key.ItemType == SkillBooks){
                        if(key.Id!=curr.Id) lst.Add(key);
                    }
                }
                foreach (var item in lst){
                    ____curReadingBook=item;
                    if(!____readingBooks.ContainsKey(____curReadingBook))____readingBooks[____curReadingBook]=default(GameData.Domains.Taiwu.ReadingBookStrategies); // 如果没有读书策略，会红字
                    __instance.UpdateReadingProgressInCombat(context); // 因为现在block是false，所以可以直接通过
                }

                // post

                for (int i = 0; i < ____referenceBooks.Length; i++){
                    if(keys[i].IsValid() && GameData.Domains.DomainManager.Item.ItemExists(keys[i]))
                    ____referenceBooks[i]=keys[i];
                }
                ____curReadingBook=curr;
                if(!____readingBooks.ContainsKey(curr))____readingBooks[curr]=default(GameData.Domains.Taiwu.ReadingBookStrategies); // 不知道为什么这个东西会红
                block=true;
            }
        }
    }


    public class YaLuckyReading { // 禁止战斗阅读，手工调用战斗读书指令
        [HarmonyTranspiler, HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain), "UpdateReadingProgressInCombat")]
        public static IEnumerable<CodeInstruction> Transpiler2(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            return instructions.MethodReplacer(typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("SetReadingEventTriggered"), typeof(YaLuckyReading).GetMethod("SetReadingEventTriggered"));
        }
        public static void SetReadingEventTriggered(GameData.Domains.Taiwu.TaiwuDomain __instance, bool value, GameData.Common.DataContext context){}
        [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CalcEvaluationList")]
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            if(typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("UpdateReadingProgressInCombat",(BindingFlags)(-1))==null){
                throw new Exception("ASmallCollectionsFromNeutron.YaLuckyReading 找不到 GameData.Domains.Taiwu.TaiwuDomain.UpdateReadingProgressInCombat方法，因此旧版灵光一闪功能暂时失效，请联系作者修复，或者关闭“不释旧卷”以禁用这一行黄字");
            }
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Callvirt,typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("GetReadInCombatCount",new Type[0]))
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Pop,null
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_0)
                    )
                ).InstructionEnumeration();
            return instructions;
        }
        [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CalcEvaluationList")]
        public static void Postfix(GameData.Common.DataContext context){
            GameData.Domains.DomainManager.Taiwu.UpdateReadingProgressInCombat(context);
        }
    }

    public class YaExtendBreak {
        [HarmonyPatch(typeof(GameData.Domains.Taiwu.BreakPlateRegions),"IsBonusGridBornRegionPos")]
        public static bool Postfix(bool __result, int plateWidth, int plateHeight, ValueTuple<byte, byte> pos){
            return pos.Item2<plateHeight-(1&~pos.Item1);
        }
        [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldc_I4_3),
                    new CodeMatch(OpCodes.Stloc_2)
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        Op_instruction,null
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"InitSkillBreakPlate")]
    public class ExtendBreak {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(i=>i.opcode==OpCodes.Ldfld && ( (FieldInfo)i.operand==typeof(Config.SkillBreakPlateItem).GetField("PlateWidth") || (FieldInfo)i.operand==typeof(Config.SkillBreakPlateItem).GetField("PlateHeight") ))
                ).Repeat( matcher => // Do the following for each match
                    matcher.Advance(1).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_3),
                        new CodeInstruction(OpCodes.Add)
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }

    [HarmonyPatch(typeof(GameData.Domains.CombatSkill.CombatSkillDomain),"GetBonusBreakGrids")]
    public class AllYellowPerkPrefix {
        public static bool Prefix(ref List<Config.BreakGrid> __result,short skillTemplateId, sbyte behaviorType){
            Config.SkillBreakGridListItem configData = Config.SkillBreakGridList.Instance[skillTemplateId];
            switch (behaviorType)
            {
            case 0:
                __result = configData.BreakGridListJust;
                break;
            case 1:
                __result = configData.BreakGridListKind;
                break;
            case 2:
                __result = configData.BreakGridListEven;
                break;
            case 3:
                __result = configData.BreakGridListRebel;
                break;
            case 4:
                __result = configData.BreakGridListEgoistic;
                break;
            default:
                __result = null;
                return false;
            }
            __result = new List<Config.BreakGrid>(__result);

            foreach(List<Config.BreakGrid> list in new List<Config.BreakGrid>[]{configData.BreakGridListJust,configData.BreakGridListKind,configData.BreakGridListEven,configData.BreakGridListRebel,configData.BreakGridListEgoistic}){
                foreach(Config.BreakGrid item in list){
                    bool flag=true;
                    for(int i=0;i<__result.Count;i++){
                        if(__result[i].BonusType==item.BonusType){
                            if(__result[i].GridCount<item.GridCount){
                                __result[i]=item;
                            }
                            flag=false;
                            break;
                        }
                    }
                    if(flag){
                        __result.Add(item);
                    }
                }
            }
            return false;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.CombatSkill.CombatSkillDomain),"GetBonusBreakGrids")]
    public class AllYellowPerkPostfix {
        public static void Postfix(ref List<Config.BreakGrid> __result,short skillTemplateId, sbyte behaviorType){
            if(enable_outline){
                __result=new List<Config.BreakGrid>(__result);
            } else {
                __result=new List<Config.BreakGrid>();
            }
            switch (Config.CombatSkill.Instance[skillTemplateId].EquipType) {
            case 0:
                for(int i=Math.Max(Config.CombatSkill.Instance[skillTemplateId].GridCost-1,(sbyte)0);i>=0;i--)__result.AddRange(AdditionalGrids0);
                break;
            case 1:
                for(int i=Math.Max(Config.CombatSkill.Instance[skillTemplateId].GridCost-1,(sbyte)0);i>=0;i--)__result.AddRange(AdditionalGrids1);
                break;
            case 2:
                for(int i=Math.Max(Config.CombatSkill.Instance[skillTemplateId].GridCost-1,(sbyte)0);i>=0;i--)__result.AddRange(AdditionalGrids2);
                break;
            case 3:
                for(int i=Math.Max(Config.CombatSkill.Instance[skillTemplateId].GridCost-1,(sbyte)0);i>=0;i--)__result.AddRange(AdditionalGrids3);
                break;
            case 4:
                for(int i=Math.Max(Config.CombatSkill.Instance[skillTemplateId].GridCost-1,(sbyte)0);i>=0;i--)__result.AddRange(AdditionalGrids4);
                break;
            default:
                break;
            }
            if(yellowFill.BonusType>=0){
                __result.Add(yellowFill);
            }
            if(yellowFill2.BonusType>=0){
                __result.Add(yellowFill2);
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"UpdateCombatSkillBookReadingProgress")]
    public class TaiwuDomainUpdateCombatSkillBookReadingProgress{
        public static MethodInfo GetTaiwuCombatSkill=typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("GetTaiwuCombatSkill",(BindingFlags)(-1));
        public static MethodInfo SetCombatSkillPageComplete=typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("SetCombatSkillPageComplete",(BindingFlags)(-1));
        public static MethodInfo SetTaiwuCombatSkill=typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("SetTaiwuCombatSkill",(BindingFlags)(-1));
        public static void Postfix(GameData.Domains.Taiwu.TaiwuDomain __instance, GameData.Common.DataContext context, GameData.Domains.Item.SkillBook book){
            short skillTemplateId=book.GetCombatSkillTemplateId();
            GameData.Domains.Taiwu.TaiwuCombatSkill taiwuCombatSkill = (GameData.Domains.Taiwu.TaiwuCombatSkill) GetTaiwuCombatSkill.Invoke(__instance, new object[]{skillTemplateId});
            for(byte i=0;i<15;i++){
                if((bool)typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("OfflineAddReadingProgress",(BindingFlags)(-1)).Invoke(__instance, new object[]{taiwuCombatSkill,i,knowOther})){
                    SetTaiwuCombatSkill.Invoke(__instance,new object[]{context, skillTemplateId, taiwuCombatSkill});
//                    taiwuCombatSkill.SetReadingState(taiwuCombatSkill.GetReadingState() | (((ushort)1)<<i),context);
                    SetCombatSkillPageComplete.Invoke(__instance, new object[]{context, book,i});
//                    taiwuCombatSkill.SetBookPageReadingProgress(i,(sbyte)100);
//                    GameData.Domains.CombatSkill.CombatSkill skillItem = GameData.Domains.DomainManager.CombatSkill.GetElement_CombatSkills(new GameData.Domains.CombatSkill.CombatSkillKey(__instance.GetTaiwuCharId(), skillTemplateId));
//                    skillItem.SetReadingState(GameData.Domains.CombatSkill.CombatSkillStateHelper.SetPageRead(skillItem.GetReadingState(), i), context);
                } else {
                    SetTaiwuCombatSkill.Invoke(__instance,new object[]{context, skillTemplateId, taiwuCombatSkill});
                }
            }
        }
    }
    public class SetLegendaryBookBonusCountYinYang {
        public static IEnumerable<MethodBase> TargetMethods(){
            yield return typeof(GameData.Domains.Extra.ExtraDomain).GetMethod("SetLegendaryBookBonusCountYin",(BindingFlags)(-1));
            yield return typeof(GameData.Domains.Extra.ExtraDomain).GetMethod("SetLegendaryBookBonusCountYang",(BindingFlags)(-1));
        }
        // [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"KillBad0Checker")]
        public static void Prefix(ref GameData.Utilities.SByteList value){
            for(int i=0;i<value.Items.Count;i++){value.Items[i]=12;}
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"UpdateCombatSkillBookReadingProgress")]
    public class TaiwuDomainUpdateCombatSkillBookReadingProgress_break{
        public static FieldInfo _practiceLevel = typeof(GameData.Domains.CombatSkill.CombatSkill).GetField("_practiceLevel",(BindingFlags)(-1));
        public static void Postfix(GameData.Domains.Taiwu.TaiwuDomain __instance, GameData.Common.DataContext context, GameData.Domains.Item.SkillBook book){
            short skillTemplateId=book.GetCombatSkillTemplateId();
            var skillKey = new GameData.Domains.CombatSkill.CombatSkillKey(GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(), skillTemplateId);

            if(GameData.Domains.DomainManager.CombatSkill.TryGetElement_CombatSkills(skillKey, out var skill) && skill.GetActivationState()==0){
                var _readingState=skill.GetReadingState();
                var configData=Config.CombatSkill.Instance[skillTemplateId];
                ushort outline=996;
                switch (configData.EquipType) {
                    case 0:if(n05_4_0)outline+=12;break; // 内功用独而非解
                    case 1:if(n05_4_1)outline-=3;break; // 催破用承而非解
                    case 2:if(n05_4_2 && (configData.Grade&7)>5)outline+=4;break; // 23品轻灵用异而非解
                    case 3:if(n05_4_3 && (configData.Grade&7)>5)outline+=12;break; // 23品护体用独而非解
                    case 4:if(n05_4_4 && (configData.Grade&7)>5)outline+=12;break; // 23品奇窍用独而非解
                }
                if(GameData.Domains.CombatSkill.CombatSkillStateHelper.HasReadOutlinePages(_readingState) && GameData.Domains.DomainManager.Taiwu.CanBreakOut(skillTemplateId)){
                    if(skill.GetRevoked())skill.SetRevoked(false,context);
                    if(skill.GetPracticeLevel()<100){
                        if(n05_4_5){
                            skill.SetPracticeLevel(100,context);
                        } else {
                            return;
                        }
                    }
                    if(n05_4_6){
                        sbyte inner=configData.EquipType==3?(sbyte)100:(sbyte)50;
                        if(skill.GetInnerRatio()!=inner)skill.SetInnerRatio(inner,context);
                    }
                    bool hasbreak=false;
                    // if(GameData.Domains.DomainManager.Extra.TryGetElement_CombatSkillCurrBreakPlateIndex(skillTemplateId, out var x) && x!=0)
                    if((_readingState & (outline+18848))==outline+18848){
                        GameData.Domains.DomainManager.Extra.ChangeCombatSkillBreakPlate(context, skillTemplateId, 1);
                        if(!GameData.Domains.DomainManager.Taiwu.TryGetElement_SkillBreakPlateDict(skillTemplateId, out var currPlate)){
                            currPlate=GameData.Domains.DomainManager.Taiwu.EnterSkillBreakPlate(context, skillTemplateId, (ushort)(outline+18848)); // 总纲+用奇源参绝，
                            GameData.Domains.DomainManager.Taiwu.SelectSkillBreakGrid(context,skillTemplateId,currPlate.EndPoint.Item2,currPlate.EndPoint.Item1);
                        }
                        hasbreak=true;
                    }
                    if((_readingState & outline)==outline){
                        GameData.Domains.DomainManager.Extra.ChangeCombatSkillBreakPlate(context, skillTemplateId, 0);
                        if(!GameData.Domains.DomainManager.Taiwu.TryGetElement_SkillBreakPlateDict(skillTemplateId, out var currPlate)){
                            currPlate=GameData.Domains.DomainManager.Taiwu.EnterSkillBreakPlate(context, skillTemplateId, outline); // 总纲解+修思源参藏，有理由怀疑茄子在暗示什么
                            GameData.Domains.DomainManager.Taiwu.SelectSkillBreakGrid(context,skillTemplateId,currPlate.EndPoint.Item2,currPlate.EndPoint.Item1);
                        }
                        hasbreak=true;
                    }
                    if(hasbreak && n05_4_7 && configData.Grade>2 && (configData.EquipType!=0 || configData.Grade<6)){
                        GameData.Domains.DomainManager.Extra.AddCharacterMasteredCombatSkill(context, GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(), skillTemplateId);
                    }
                }
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CalcLootItem")]
    public class ZhouBaPi{
        public static void Prefix(GameData.Domains.Combat.CombatDomain __instance, bool ____isBossPuppetCombat, sbyte ____combatType,sbyte ____combatStatus, int[]____enemyTeam, List<int>____lootCharList, Dictionary<int,GameData.Domains.Combat.CombatCharacter>____combatCharacterDict, GameData.Common.DataContext context){
            if(____combatType == 0 || ____combatType == 3 || ____combatStatus != GameData.Domains.Combat.CombatStatusType.EnemyFail || __instance.CombatConfig.LootItemRate <= 0 || ____isBossPuppetCombat){
                return;
            }
            var taiwu=GameData.Domains.DomainManager.Taiwu.GetTaiwu();
            var tr=taiwu.GetResources();
            var zero=default(GameData.Domains.Character.ResourceInts);
            foreach(int enemyId in ____enemyTeam){
                if (!(enemyId < 0 || ____lootCharList.Contains(enemyId))) {
                    var enemyChar = ____combatCharacterDict[enemyId].GetCharacter();
                    var er=enemyChar.GetResources();
                    tr.Add(ref er);
                    enemyChar.SetResources(ref zero, context);
                }
            }
            taiwu.SetResources(ref tr, context);
        }
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Call,typeof(GameData.Utilities.RedzenHelper).GetMethod("CheckPercentProb"))
                ).Repeat( matcher => // Do the following for each match
                    matcher.InsertAndAdvance(
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Ldc_I4_S,100)
                    ).Advance(1)
                ).InstructionEnumeration();
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Call,typeof(Math).GetMethod("Min",new Type[]{typeof(int),typeof(int)}))
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Pop,null
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"AdjustLifespan")]
    public class HuanYue {
        public static void Prefix(ref short ____health, ref short ____baseMaxHealth, short ____templateId){
            if(____templateId==StoryHuanyue){
                ____baseMaxHealth=Math.Max((short)HuanYueNine,____baseMaxHealth);
                ____health=32767; // 反正后面有一手clamp
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"GenerateRandomBasicFeatures")]
//    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"OfflineCreateProtagonistRandomFeatures")]
    public class AllFeature {
//        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
//            return Transpilers.MethodReplacer(instructions,typeof(GameData.Domains.Character.Character).GetMethod("GenerateRandomBasicFeatures",(BindingFlags)(-1)),typeof(AllFeature).GetMethod("MG"));
//        }

        public static FieldInfo _lifeSkillQualificationGrowthType=typeof(GameData.Domains.Character.Character).GetField("_lifeSkillQualificationGrowthType",(BindingFlags)(-1));
        public static FieldInfo _combatSkillQualificationGrowthType=typeof(GameData.Domains.Character.Character).GetField("_combatSkillQualificationGrowthType",(BindingFlags)(-1));

        public static ushort FieldName2FieldId_LifeSkillQualificationGrowthType=GameData.Domains.Character.CharacterHelper.FieldName2FieldId["LifeSkillQualificationGrowthType"];
        public static ushort FieldName2FieldId_CombatSkillQualificationGrowthType=GameData.Domains.Character.CharacterHelper.FieldName2FieldId["CombatSkillQualificationGrowthType"];
        public static unsafe bool Prefix(GameData.Domains.Character.Character __instance, GameData.Common.DataContext context, Dictionary<short, short> featureGroup2Id, bool isProtagonist, bool allGoodBasicFeatures, ref GameData.Domains.Character.LifeSkillShorts ____baseLifeSkillQualifications, ref GameData.Domains.Character.CombatSkillShorts ____baseCombatSkillQualifications, ref GameData.Domains.Character.MainAttributes ____baseMainAttributes,  ref GameData.Domains.Character.LifeSkillShorts ____lifeSkillQualifications, ref GameData.Domains.Character.CombatSkillShorts ____combatSkillQualifications){
//            if(____templateId==StoryHuanyue){
//                ____maxHealth=Math.Max((short)HuanYueNine,____maxHealth);
//                return true;
//            }else
            if(!(isProtagonist || allGoodBasicFeatures)){
                return true;
            }
            fixed(short*ptr=____baseLifeSkillQualifications.Items)for (int i = 0; i < 16; i++){
                *(ptr+i)=Math.Max(*(ptr+i),(short)minLife);
            }
            fixed(short*ptr=____baseCombatSkillQualifications.Items)for (int i = AFBegin; i < 14; i++){ // avoid finger check
                *(ptr+i)=Math.Max(*(ptr+i),(short)minCombat);
            }
            fixed(short*ptr=____baseMainAttributes.Items)for (int i = 0; i < 6; i++){
                *(ptr+i)=Math.Max(*(ptr+i),(short)minMain);
            }
            ____lifeSkillQualifications=____baseLifeSkillQualifications;
            ____combatSkillQualifications=____baseCombatSkillQualifications;

            var alist=new List<short>();
            var yalist=new List<short>();
            foreach (Config.CharacterFeatureItem item in ((IEnumerable<Config.CharacterFeatureItem>)Config.CharacterFeature.Instance)) {if (item != null) {
                    if (item.Basic) {
                        if (item.CandidateGroupId == 0) {
                            alist.Add(item.TemplateId);
                        } else if (item.CandidateGroupId == 1) {
                            yalist.Add(item.TemplateId);
                            //for (int k = 0; k < (int)item.AppearProb; k++)
                            //{
                            //    CharacterDomain._normalNegativeBasicFeaturesPool.Add(item.TemplateId);
                            //}
                            //for (int l = 0; l < (int)item.ProtagonistAppearProb; l++)
                            //{
                            //    CharacterDomain._protagonistNegativeBasicFeaturesPool.Add(item.TemplateId);
                            //}
                        } else {
                            // alist.Add(item.TemplateId); // 无根之人 石芯玉女 阴阳一体
                        }
                    }
                }
            }
            if(WuLinTraitLevel>0){
                alist.Add((short)(DefKey_HaveElixir2+WuLinTraitLevel-3));
                alist.Add((short)(DefKey_GreenMotherSpiderPoison2+WuLinTraitLevel-3));
                alist.Add((short)(DefKey_StarsRegulateBreath2+WuLinTraitLevel-3));
                alist.Add((short)(DefKey_SupportFromShixiang2+WuLinTraitLevel-3));
            }
            var pos=new Dictionary<short, short>();
            var neg=new Dictionary<short, short>();
            foreach (short featureId in alist) {
                Config.CharacterFeatureItem template = Config.CharacterFeature.Instance[featureId];
                if((!pos.ContainsKey(template.MutexGroupId))||featureId>pos[template.MutexGroupId]){
                    pos[template.MutexGroupId]=featureId;
                }
            }
            foreach (short featureId in yalist) {
                Config.CharacterFeatureItem template = Config.CharacterFeature.Instance[featureId];
                if((!neg.ContainsKey(template.MutexGroupId))||featureId>neg[template.MutexGroupId]){
                    neg[template.MutexGroupId]=featureId;
                }
            }
            // 如果你准备删除多余三级特性

            int posc=N01APC==30?pos.Count:Math.Min(pos.Count,N01APC);
            int negc=N01ANC==30?neg.Count:Math.Min(neg.Count,N01ANC);
            Random random = new Random();
            while(posc>0 || negc>0){
                Dictionary<short, short> dict;
                if(posc>=negc){
                    dict=pos;
                    posc--;
                } else {
                    dict=neg;
                    negc--;
                }
                if(dict.Count>0){
                    int index = random.Next(dict.Count);
                    using (var enumerator = dict.Keys.GetEnumerator()) {
                        while (enumerator.MoveNext()) {
                            if (index <= 0) {
                                featureGroup2Id[enumerator.Current]=dict[enumerator.Current];
                                pos.Remove(enumerator.Current);
                                neg.Remove(enumerator.Current);
                                break;
                            }
                            index--;
                        }
                    }
                }
            }
            if(fulongCF && allGoodBasicFeatures){
                featureGroup2Id[Config.CharacterFeature.Instance[DefKey_FulongServant].MutexGroupId]=DefKey_FulongServant;
            }
            foreach(var ids in manual_feature_id){
                featureGroup2Id[Config.CharacterFeature.Instance[ids].MutexGroupId]=ids;
            }
            if(N01bloom!=-1){
                if(__instance.GetLifeSkillQualificationGrowthType()!=(sbyte)N01bloom){
                    // 因为这里是创建人物，还没有将人物存档，所以不必刷新存档数据
                    // 或者说，这里只要刷新必然报错，而不刷新则可以正常存档这些属性
                    _lifeSkillQualificationGrowthType.SetValue(__instance,(sbyte)N01bloom);
                    // __instance.InvalidateSelfAndInfluencedCache(FieldName2FieldId_LifeSkillQualificationGrowthType,context);
                    //logger("changing LifeSkillQualificationGrowthType for "+__instance.GetId());
                    // *(sbyte*)GameData.ArchiveData.OperationAdder.DynamicObjectCollection_SetFixedField<int>(__instance.CollectionHelperData.DomainId, __instance.CollectionHelperData.DataId, __instance.GetId(), offset_lifeSkillQualificationGrowthType, 1)=(sbyte)N01bloom;
                }
                if(__instance.GetCombatSkillQualificationGrowthType()!=(sbyte)N01bloom){
                    _combatSkillQualificationGrowthType.SetValue(__instance,(sbyte)N01bloom);
                    // __instance.InvalidateSelfAndInfluencedCache(FieldName2FieldId_CombatSkillQualificationGrowthType,context);
                    //logger("changing CombatSkillQualificationGrowthType for "+__instance.GetId());
                    // *(sbyte*)GameData.ArchiveData.OperationAdder.DynamicObjectCollection_SetFixedField<int>(__instance.CollectionHelperData.DomainId, __instance.CollectionHelperData.DataId, __instance.GetId(), offset_combatSkillQualificationGrowthType, 1)=(sbyte)N01bloom;
                }
            }
            return false;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"CalcPracticeResult")]
    public class FastPractice {
        public static int Postfix(int result){
            return fpv;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.CombatSkill.CombatSkill),"GetBreakoutAvailableStepsCount")]
    public class BreakPlus {
        public static sbyte Postfix(sbyte result){
            return (sbyte)gbasc;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CheckRopeOrSwordHit")]
    public class AlwaysCapture {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Call,typeof(GameData.Utilities.RedzenHelper).GetMethod("CheckPercentProb"))
                ).Repeat( matcher => // Do the following for each match
                    matcher.InsertAndAdvance(
                        new CodeInstruction(OpCodes.Pop),
                        new CodeInstruction(OpCodes.Ldc_I4_S,100)
                    ).Advance(1)
                ).InstructionEnumeration();
            if(N03_2)instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(GameData.Domains.Combat.CombatDomain).GetField("_combatType",(BindingFlags)(-1))),
                    new CodeMatch(OpCodes.Ldelem_I1)
                ).Repeat( matcher => // Do the following for each match
                    matcher.SetAndAdvance(
                        OpCodes.Pop,null
                    ).SetAndAdvance(
                        OpCodes.Pop,null
                    ).InsertAndAdvance(
                        new CodeInstruction(OpCodes.Ldc_I4_0)
                    )
                ).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"OfflineMakeLove")]
    public class PatchPregnant {
        public static MethodInfo OfflineAddFeature=typeof(GameData.Domains.Character.Character).GetMethod("OfflineAddFeature",(BindingFlags)(-1));
        public static bool Prefix(ref bool __result, GameData.Domains.Character.Character father, GameData.Domains.Character.Character mother){
            if(mother.GetFeatureIds().Contains(DefKey_Pregnant)){
                __result=false;
                OfflineAddFeature.Invoke(father,MakeLove_param);
//                logger("id"+mother.GetId()+"已经怀孕");
                return false;
            } else {
//                logger("id"+mother.GetId()+"可以怀孕");
                return true;
            }
        }
//        public static void Postfix(ref bool __result, GameData.Domains.Character.Character father, GameData.Domains.Character.Character mother){
//            logger("id"+mother.GetId()+"的返回值是"+__result+"，受孕状态是"+mother.GetFeatureIds().Contains(DefKey_Pregnant));
//        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.CharacterDomain),"UpdateLuckEvents")]
    public class LuckyTaiwu {
        public static MethodInfo ApplyLucky_CombatSkillBook=typeof(GameData.Domains.Character.CharacterDomain).GetMethod("ApplyLucky_CombatSkillBook",(BindingFlags)(-1));
        public static MethodInfo ApplyLucky_LifeSkillBook=typeof(GameData.Domains.Character.CharacterDomain).GetMethod("ApplyLucky_LifeSkillBook",(BindingFlags)(-1));
        public static MethodInfo ApplyLucky_Regen=typeof(GameData.Domains.Character.CharacterDomain).GetMethod("ApplyLucky_Regen",(BindingFlags)(-1));
        public unsafe static void Prefix(GameData.Domains.Character.CharacterDomain __instance, GameData.Common.DataContext context){
            var luckyChars=new List<int>(){GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId()};
            if(GameData.Utilities.RedzenHelper.CheckPercentProb(context.Random, pCombat2))for(int i=0;i<cCombat;i++)ApplyLucky_CombatSkillBook.Invoke(GameData.Domains.DomainManager.Character,new object[]{context, luckyChars, 1, (sbyte)pCombat});
            if(GameData.Utilities.RedzenHelper.CheckPercentProb(context.Random, pLife2))for(int i=0;i<cLife;i++)ApplyLucky_LifeSkillBook.Invoke(GameData.Domains.DomainManager.Character,new object[]{context, luckyChars, 1, (sbyte)pLife});
            if(GameData.Utilities.RedzenHelper.CheckPercentProb(context.Random, pRegen2))for(int i=0;i<cRegen;i++)ApplyLucky_Regen.Invoke(GameData.Domains.DomainManager.Character,new object[]{context, luckyChars, 1, (sbyte)pRegen});
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"OfflineCalcGeneralAction_RandomActions")]
    public class MustLearn {
        public static MethodInfo OfflineCalcGeneralAction_TeachSkill=typeof(GameData.Domains.Character.Character).GetMethod("OfflineCalcGeneralAction_TeachSkill",(BindingFlags)(-1));
        //public static MethodInfo OfflineCalcGeneralAction_LifeSkill=typeof(GameData.Domains.Character.Character).GetMethod("OfflineCalcGeneralAction_LifeSkill",(BindingFlags)(-1));
        public unsafe static void Prefix(GameData.Domains.Character.Character __instance, GameData.Common.DataContext context, GameData.Domains.Character.ParallelModifications.PeriAdvanceMonthGeneralActionModification mod, HashSet<int> currBlockChars, ref GameData.Domains.Character.Ai.ActionEnergySbytes ____actionEnergies){
            if(currBlockChars.Contains( GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId())){
                var hs=new HashSet<int>{GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId()};
                GameData.Domains.Character.Relation.RelatedCharacter relation;
                fixed(byte*ptr=____actionEnergies.Items)if(GameData.Domains.DomainManager.Character.TryGetRelation(__instance.GetId(), GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(), out relation) && ((relation.RelationType & RelationType_SwornBrotherOrSister) !=0)){
                    for(int i=0;i<totalTeachCount;i++){
                        *(ptr+4)=200;
                        OfflineCalcGeneralAction_TeachSkill.Invoke(__instance, new object[]{context,mod,hs,hs});
                        if(*(ptr+4)==200){
                            break;
                        }
                    }
                } else {
                    GameData.Domains.DomainManager.Character.AddRelation(context, __instance.GetId(), GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(),  RelationType_SwornBrotherOrSister , GameData.Domains.DomainManager.World.GetCurrDate());
                    for(int i=0;i<totalTeachCount;i++){
                        *(ptr+4)=200;
                        OfflineCalcGeneralAction_TeachSkill.Invoke(__instance, new object[]{context,mod,hs,hs});
                        if(*(ptr+4)==200){
                            break;
                        }
                    }
                    GameData.Domains.DomainManager.Character.ChangeRelationType(context, __instance.GetId(), GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(),  RelationType_SwornBrotherOrSister , 0);
                    GameData.Domains.DomainManager.Character.ChangeRelationType(context, GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(), __instance.GetId(),  RelationType_SwornBrotherOrSister , 0);
                }
            }
        }
        [HarmonyPostfix]
        [HarmonyPatch(typeof(GameData.Domains.Character.Ai.AiHelper.GeneralActionConstants),"GetAskToTeachSkillRespondChance")]
        public static sbyte HackChance(sbyte result){
            //logger("检查了传授概率，返回100.");
            return (sbyte)100;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"SetTaiwu")]
    public class TaiwuLegency {
        public static void Prefix(GameData.Common.DataContext context, GameData.Domains.Character.Character newTaiwuChar, GameData.Domains.Character.Character ____taiwuChar) {
            if(____taiwuChar==null)return;
            foreach(var feature in ____taiwuChar.GetFeatureIds()){
                if(Config.CharacterFeature.Instance[feature].GeneticProb>0){
                    newTaiwuChar.AddFeature(context, feature, twoverwrite);
                }
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"SetTaiwu")]
    public class TaiwuLegencyAttribute {
        public unsafe static void Prefix(GameData.Common.DataContext context, GameData.Domains.Character.Character newTaiwuChar, GameData.Domains.Character.Character ____taiwuChar) {
            if(____taiwuChar==null)return;
            {
                var x=newTaiwuChar.GetBaseLifeSkillQualifications();
                var y=____taiwuChar.GetBaseLifeSkillQualifications();
                for (int i = 0; i < 16; i++){
                    *(x.Items+i)=Math.Max(*(x.Items+i), (short)(((int)(*(y.Items+i)))*inhertlife/10000));
                }
                newTaiwuChar.SetBaseLifeSkillQualifications(ref x,context);
            }
            {
                var x=newTaiwuChar.GetBaseCombatSkillQualifications();
                var y=____taiwuChar.GetBaseCombatSkillQualifications();
                for (int i = 0; i < 14; i++){
                    *(x.Items+i)=Math.Max(*(x.Items+i), (short)(((int)(*(y.Items+i)))*inhertcombat/10000));
                }
                newTaiwuChar.SetBaseCombatSkillQualifications(ref x,context);
            }
            {
                var x=newTaiwuChar.GetBaseMainAttributes();
                var y=____taiwuChar.GetBaseMainAttributes();
                for (int i = 0; i < 16; i++){
                    *(x.Items+i)=Math.Max(*(x.Items+i), (short)(((int)(*(y.Items+i)))*inhertmain/10000));
                }
                newTaiwuChar.SetBaseMainAttributes(x,context);
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.TaiwuDomain),"ClearBreakPlate")]
    public class Printing {
        public static FieldInfo _pageIncompleteState=typeof(GameData.Domains.Item.SkillBook).GetField("_pageIncompleteState",(BindingFlags)(-1));
        //public static MethodInfo GetTaiwuCombatSkill=typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("GetTaiwuCombatSkill",(BindingFlags)(-1));
        public static void Prefix(short skillTemplateId, GameData.Common.DataContext context){
            GameData.Domains.CombatSkill.CombatSkill cs;
            if(GameData.Domains.DomainManager.CombatSkill.TryGetElement_CombatSkills(new GameData.Domains.CombatSkill.CombatSkillKey(GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId(), skillTemplateId),out cs) ) {
                var state=cs.GetActivationState();
                state=(ushort)(((state>>1)&0x5555)+(state&0x5555));
                state=(ushort)(((state>>2)&0x3333)+(state&0x3333));
                state=(ushort)(((state>>4)+state)&0x0F0F);
                state=(ushort)(((state>>8)+state)&0x00FF);
                if(state==6){
                    var bid=Config.CombatSkill.Instance[skillTemplateId].BookId;
                    if(bid>=0){
                        var key=GameData.Domains.DomainManager.Item.CreateSkillBook(context, bid, cs.GetActivationState());

                        var item = GameData.Domains.DomainManager.Item.GetElement_SkillBooks(key.Id);
                        _pageIncompleteState.SetValue(item, (ushort)0);
                        // int itemId = GameData.Domains.DomainManager.Item.GenerateNextItemId(context);
                        // var item = new GameData.Domains.Item.SkillBook(context.Random, bid, itemId, cs.GetActivationState());
                        // _pageIncompleteState.SetValue(item, (ushort)0);
                        // GameData.Domains.DomainManager.Item.AddElement_SkillBooks(itemId, item);
                        GameData.Domains.DomainManager.Taiwu.GetTaiwu().AddInventoryItem(context, key, 1);
                    }
                    logger("got skillbook with id "+bid);
                } else {
                    logger("does not satisfy, state="+cs.GetActivationState()+", sum="+state);
                }
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.World.WorldDomain),"GetProbAdjustOfCreatingCharacter")]
    public class DecreasePopulation {
        public static float Postfix(float result){
            return result*(float)GetProbAdjustOfCreatingCharacter/10000f;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Character.Character),"GetFertility")]
    public class TaiwuBlood {
        //public static MethodInfo GetTaiwuCombatSkill=typeof(GameData.Domains.Taiwu.TaiwuDomain).GetMethod("GetTaiwuCombatSkill",(BindingFlags)(-1));
        public static bool Prefix(ref short __result, GameData.Domains.Character.Character __instance){
            if(__instance.GetFeatureIds().Contains(MengJingZhongRen)){
                __result=(short)TaiwuBloodFertility;
                return false;
            } else {
                return true;
            }
        }
    }
    public class KillBadChecker {
        public static IEnumerable<MethodBase> TargetMethods(){
            yield return typeof(GameData.Domains.Combat.CombatDomain).GetMethod("KillBad0Checker",(BindingFlags)(-1));
            yield return typeof(GameData.Domains.Combat.CombatDomain).GetMethod("KillBad1Checker",(BindingFlags)(-1));
        }
        // [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"KillBad0Checker")]
        public static void Postfix(bool __result, GameData.Domains.Combat.CombatDomain __instance){
            if(__result){
                var x=GameData.Domains.DomainManager.Combat.GetMainCharacter(true).GetCharacter().GetLocation();
                if(!x.IsValid()){return;}
                var areaData=GameData.Domains.DomainManager.Map.GetElement_Areas((int)x.AreaId);
                if(areaData.SettlementInfos!=null){
                    var context=GameData.Common.DataContextManager.GetCurrentThreadDataContext();
                    foreach (var settlementInfo in areaData.SettlementInfos) {
                        if (settlementInfo.SettlementId>=0){
                            var settlement = GameData.Domains.DomainManager.Organization.GetSettlement(settlementInfo.SettlementId);
                            settlement.SetSafety((short)Math.Min((int)settlement.GetSafety() + 1, (int)settlement.GetMaxSafety()), context);
                            settlement.SetCulture((short)Math.Min((int)settlement.GetCulture() + 1, (int)settlement.GetMaxCulture()), context);
                            // logger("Safety and Culture triggered to "+settlementInfo.SettlementId);
                        }
                    }
                }
                // logger("KillBadChecker triggered.");
            }
        }
    }
    public class Master {
        // [HarmonyPrefix, HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionData),"IsProfessionAvailable")]
        // public static bool Prefix1(ref bool __result){
        //     return !(__result=true);
        // }
        [HarmonyPrefix, HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionData),"IsSkillCooldown")]
        public static bool Prefix2(ref bool __result){
            return __result=false;
        }
        [HarmonyPrefix, HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionData),"OfflineSkillCooldown")]
        public static bool Prefix3(){
            return false;
        }
        [HarmonyTranspiler, HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionSkillHandle),"OnSkillExecuted")]
        public static IEnumerable<CodeInstruction> Transpiler_nullify_CostTimeWhenFinished(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            return instructions.MethodReplacer(typeof(GameData.Domains.World.WorldDomain).GetMethod("AdvanceDaysInMonth"), typeof(Master).GetMethod("NoAdvanceDaysInMonth"));
        }
        public static void NoAdvanceDaysInMonth(GameData.Domains.World.WorldDomain instance, GameData.Common.DataContext context, int days){}
    }
    public class Master0 {
        [HarmonyTranspiler, HarmonyPatch(typeof(GameData.Domains.Extra.ExtraDomain),"ChangeProfession")]
        public static IEnumerable<CodeInstruction> Transpiler_SubtractedCurrDate(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            return instructions.MethodReplacer(typeof(GameData.Domains.World.WorldDomain).GetMethod("GetCurrDate"), typeof(Master0).GetMethod("GetDateOneYearAgo"));
        }
        public static int GetDateOneYearAgo(GameData.Domains.World.WorldDomain instance){
            return instance.GetCurrDate()-12;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Extra.ExtraDomain),"GetSeniorityBonusFactor")]
    public class MasterExp {
        public static int Postfix(int result) {
            return result*b1val/100;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionData),"GetSeniorityTreatmentCharge")]
    public class MasterDoctor {
        public static int Postfix(int result) {
            return result*b2val/100;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.TaiwuEvent.EventHelper.EventHelper),"ExecuteMartialArtistSkill2")]
    public class MasterMartialArtistSkill {
        public static bool Prefix(sbyte combatSkillType) {
            GameData.Domains.Taiwu.Profession.ProfessionData professionData = GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
            for(int i=0;i<b3val;i++){
                GameData.Domains.Taiwu.Profession.ProfessionSkillHandle.MartialArtistSkill_MakeAreaLearnCombatSkill(GameData.Domains.DomainManager.TaiwuEvent.MainThreadDataContext, professionData, combatSkillType);
            }
            return false;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.TaiwuEvent.EventHelper.EventHelper),"ExecuteLiteratiSkill2")]
    public class MasterLiteratiSkill {
        public static bool Prefix(sbyte lifeSkillType) {
            GameData.Domains.Taiwu.Profession.ProfessionData professionData = GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
            for(int i=0;i<b4val;i++){
                GameData.Domains.Taiwu.Profession.ProfessionSkillHandle.LiteratiSkill_MakeAreaLearnLifeSkill(GameData.Domains.DomainManager.TaiwuEvent.MainThreadDataContext, professionData, lifeSkillType);
            }
            return false;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.LegendaryBook.LegendaryBookDomain),"CreateLegendaryBooksAccordingToXiangshuProgress")]
    public class BookSummon {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            return instructions.MethodReplacer(typeof(GameData.Domains.World.WorldDomain).GetMethod("GetXiangshuLevel"), typeof(BookSummon).GetMethod("Nine"));
        }
        public static sbyte Nine(GameData.Domains.World.WorldDomain instance){
            return 9;
        }
    }
    public class BookOwnersIsTaiwu {
        public static IEnumerable<MethodBase> TargetMethods(){
            foreach(var x in B06.Split(",")){
                MethodBase z=null;
                try {
                    if(x!="") z=typeof(GameData.Domains.Extra.ExtraDomain).GetMethod(x,(BindingFlags)(-1));
                } catch (Exception ex){
                    logwarn("在修改奇书项目"+x+"时出错，错误原因如下");
                    logex(ex);
                    logwarn("上述错误不影响游戏执行，但请最好告知作者错误的发生，以便作者进行修改");
                }
                if(z!=null)yield return z;
            }
        }
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            return instructions.MethodReplacer(typeof(GameData.Domains.LegendaryBook.LegendaryBookDomain).GetMethod("GetElement_BookOwners"), typeof(BookOwnersIsTaiwu).GetMethod("Taiwu"));
        }
        public static int Taiwu(GameData.Domains.LegendaryBook.LegendaryBookDomain instance, int index){
            return GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId();
        }
    }
    public class TaiwuIsComboMaster {
        [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CanPursue")]
        public static bool Prefix(ref bool __result, GameData.Domains.Combat.CombatDomain __instance, GameData.Domains.Combat.CombatCharacter character){
            if(character.IsAlly){
                __result=true;
                return false;
            } else {return true;}
        }
    }
    public class OnlyTaiwuIsComboMaster {
        [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CanPursue")]
        public static bool Prefix(ref bool __result, GameData.Domains.Combat.CombatDomain __instance, GameData.Domains.Combat.CombatCharacter character){
            __result=character.IsAlly;
            return false;
        }
    }
    public class PeopleAreComboMaster {
        [HarmonyPatch(typeof(GameData.Domains.Combat.CombatDomain),"CanPursue")]
        public static bool Prefix(ref bool __result, GameData.Domains.Combat.CombatDomain __instance, GameData.Domains.Combat.CombatCharacter character){
            __result=true;
            return false;
        }
    }
    public class UndeadCricket {
        [HarmonyPatch(typeof(GameData.Domains.Item.ItemDomain),"UpdateCrickets")]
        public static bool Prefix(HashSet<GameData.Domains.Item.ItemKey> ____newDeadCrickets){
            ____newDeadCrickets.Clear();
            return false;
        }
    }
    public class Science {
        [HarmonyPatch(typeof(GameData.Domains.Item.ItemDomain),"SetRefinedEffects")]
        public static void Prefix(ref short materialTemplateId){
            materialTemplateId+=(short)(6-(materialTemplateId%7));
        }
    }
    public class BetterAssign {
        [HarmonyPatch(typeof(GameData.Domains.Character.Creation.CharacterCreation),"DistributeValues")]
        public unsafe static void Prefix(short* weights, int count, ref int sum){
            sum=Math.Max(sum,GameData.Utilities.CollectionUtils.GetSum(weights, count));
        }
    }
    public class FastTao {
        [HarmonyPatch(typeof(GameData.Domains.Taiwu.Profession.ProfessionSkillHandle),"TaoistMonkSkill_ConfirmTribulationSucceed")]
        public static void Prefix(){
             var featureIds=GameData.Domains.DomainManager.Taiwu.GetTaiwu().GetFeatureIds();
             if(!featureIds.Contains(393)){
                 featureIds.Add(393);
            }
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain), "ExchangeBlockData")]
    public static class MoveGrid {
        public static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            instructions = new CodeMatcher(instructions)
                // 26	004E	ldfld	int8 Config.BuildingBlockItem::MaxDurability
                // 27	0053	ldc.i4.2
                // 28	0054	div
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldfld,typeof(Config.BuildingBlockItem).GetField("MaxDurability",(BindingFlags)(-1))),
                    new CodeMatch(OpCodes.Ldc_I4_2),
                    new CodeMatch(OpCodes.Div)
                ).Repeat( (matcher) => {// Do the following for each match
                    logger("ExchangeBlockData modify maxdurability.");
                    matcher.Advance(1).SetAndAdvance(
                        OpCodes.Nop,null
                    ).SetAndAdvance(
                        OpCodes.Nop,null
                    ).Advance(1); // advance(1)结尾是美德
                }).InstructionEnumeration();
            return instructions;
        }
    }
    [HarmonyPatch(typeof(GameData.Domains.Organization.Settlement), "CalcCultureAndSafety")]
    public class MaximizeCultureAndSafety {
        public static bool Prefix(short configValue, ref ValueTuple<short,short> __result){
            short maxValue=0;
            if (configValue < 0) {
                maxValue = (short)(5*-configValue);
            } else if (configValue>0) {
                maxValue=(short)(configValue+25);
            }
            __result=((short)(maxValue >> 1),maxValue);
            return false;
        }
    }
    public class EventHelperStartSelectSoul {
        [HarmonyTranspiler]
        [HarmonyPatch(typeof(GameData.Domains.TaiwuEvent.EventHelper.EventHelper),"StartSelectSoul")]
        public static IEnumerable<CodeInstruction> Transpiler_Max(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
            // logger("in");
            instructions = new CodeMatcher(instructions)
                .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                    new CodeMatch(OpCodes.Ldc_I4_S,(sbyte)12)
                ).Repeat( matcher => // Do the following for each match
                    {
                        matcher.SetAndAdvance(
                            OpCodes.Ldc_I4_S,(sbyte)120
                        );
                        // logger("found EventHelperStartSelectSoul");
                    }
                ).InstructionEnumeration();
            return instructions;
        }
    }
    public class BuildingDomainGetTaiwuShrineStudentList {
        [HarmonyPatch(typeof(GameData.Domains.Building.BuildingDomain),"GetTaiwuShrineStudentList")]
        public static void Postfix(List<int> __result){
            __result.Add(GameData.Domains.DomainManager.Taiwu.GetTaiwuCharId());
        }
    }
}
